var ReplTool = require('./lib/easy-repl/repl').REPL_Mode;
var EasyMongo = require("./common").EasyMongo;
var cl = require('./lib/crawler').Crawler;
var al = require('./lib/analyser').Analyzer;
var repl = new ReplTool();

console.log("************************* Command Tools For Super Turtle **********************");

/**
 *  operation set closure
 * */
var request = {
    addRequest: function (seriesName) {
        if (!seriesName) {
            repl.question("Please input chain name:\n", function (data) {
                if (validateExit(data)) return;
                var seriesName = data;
                add(seriesName);
            });
        } else {
            add(seriesName);
        }
        function add(seriesName) {
            console.log("\nNOTICE Chain Config is JSON format : \nAttributes in[url,method,option,sequence,filter],\nfilter has params of[err,res,body,next]\n");
            (function questionChain() {
                repl.question("Input chain configuration :\n", function (data) {
                    if (validateExit(data)) return;
                    try {
                        var obj = eval("(" + data + ")");
                        obj.series = seriesName;
                        EasyMongo.add('request', obj, function () {
                            console.log("R-E-P-L : success add chain config of " + seriesName);
                            questionChain();
                        });
                    } catch(e){
                        if(e) console.log("Wrong input.Please retry.");
                        questionChain();
                    }
                });
            })();
        }
    },
    updateRequest: function(seriesName){
        if (!seriesName) {
            repl.question("Please input chain name:\n", function (data) {
                if (validateExit(data)) return;
                var seriesName = data;
                update(seriesName);
            });
        } else {
            update(seriesName);
        }
        function update(seriesName) {
            repl.question("Input update chain sequence :\n", function (data) {
                if (validateExit(data)) return;
                console.log("\nNOTICE Update Format is JSON : \nExample : {updateAttribute:'updateValue'}\n");
                var seq = data;
                (function updatedValue() {
                    repl.question("Input update chain configuration :\n",function(data){
                        if (validateExit(data)) return;
                        try {
                            var obj = eval("(" + data + ")");
                            EasyMongo.update("request",{series:seriesName,sequence:parseInt(seq)},obj,function(err,count){
                                if(err) {
                                    console.log("Wrong input.Please retry.");
                                    updatedValue();
                                } else {
                                    if(count != 0) {
                                        console.log("R-E-P-L : success update chain config of " + seriesName + ",seq "+seq);
                                    } else {
                                        console.log("R-E-P-L : updated 0 items.check your condition");
                                    }
                                }
                            });
                        } catch(e){
                            if(e) console.log("Wrong input.Please retry.");
                            updatedValue();
                        }
                    });
                })();
            });
        }
    },
    listRequest : function(seriesName){
        if (!seriesName) {
            repl.question("Please input chain name:\n", function (data) {
                if(!data){
                    list();
                    return;
                }
                var seriesName = data;
                list(seriesName);
            });
        } else {
            list(seriesName);
        }
        function list(seriesName){
            EasyMongo.find("request",{series:seriesName},function(err,docs){
                if(!!docs && docs.length != 0) {
                    console.log("R-E-P-L :  List Result...");
                    docs.forEach(function(obj){
                        console.log(obj);
                    });
                    console.log("R-E-P-L :  List Result Completed...");
                } else {
                    console.log("R-E-P-L : find 0 items.check your condition");
                }
            });
        }
    },
    deleteRequest: function(seriesName){
        if (!seriesName) {
            repl.question("Please input chain name:\n", function (data) {
                if (validateExit(data)) return;
                var seriesName = data;
                deleteReq(seriesName);
            });
        } else {
            deleteReq(seriesName);
        }
        function deleteReq(seriesName) {
            function deleteAll(){
                EasyMongo.remove('request',{series:seriesName},function(err,count){
                    if(err || count == 0) {
                        console.log("R-E-P-L : Deleted 0 items.check your condition");
                    } else {
                        console.log("R-E-P-L : Deleted "+count+" items.");
                    }
                });
            }
            repl.question("Input delete condition :\n", function (data) {
                if(!data) {
                    deleteAll();
                    return;
                }
                if (validateExit(data)) return;
                try {
                    var obj = eval("(" + data + ")");
                    if(obj.sequence) {
                        obj.sequence = parseInt(obj.sequence);
                    }
                    obj.series = seriesName;
                    EasyMongo.remove("request",obj,function(err,count){
                        if(err) {
                            console.log("DB ERROR..");
                        } else {
                            if(count != 0) {
                                console.log("R-E-P-L : success update chain config of " + seriesName);
                            } else {
                                console.log("R-E-P-L : updated 0 items.check your condition");
                            }
                        }
                    });
                } catch(e){
                    if(e) console.log("Wrong input.Please retry.");
                }
            });
        }
    }
};

var executor = {
    addExecutor: function (seriesName) {
        if (!seriesName) {
            repl.question("Please input executorSeries' name:\n", function (data) {
                if (validateExit(data)) return;
                var seriesName = data;
                add(seriesName);
            });
        } else {
            add(seriesName);
        }
        function add(seriesName) {
            console.log("\nNOTICE Executor Config is JSON format : \nAttributes in[col,method],\nfilter has param [data]\n");
            (function questionChain() {
                repl.question("Input executor configuration :\n", function (data) {
                    if (validateExit(data)) return;
                    try {
                        var obj = eval("(" + data + ")");
                        obj.name = seriesName;
                        EasyMongo.add('executor', obj, function () {
                            console.log("R-E-P-L : success add executor config of " + seriesName);
                            questionChain();
                        });
                    } catch(e){
                        if(e) console.log("Wrong input.Please retry.");
                        questionChain();
                    }
                });
            })();
        }
    },
    updateExecutor: function(seriesName){
        if (!seriesName) {
            repl.question("Please input executor name:\n", function (data) {
                if (validateExit(data)) return;
                var seriesName = data;
                update(seriesName);
            });
        } else {
            update(seriesName);
        }
        function update(seriesName) {
            repl.question("Input update executor column :\n", function (data) {
                if (validateExit(data)) return;
                console.log("\nNOTICE Update Format is JSON : \nExample : {updateAttribute:'updateValue'}\n");
                var col = data;
                (function updatedValue() {
                    repl.question("Input update executor configuration :\n",function(data){
                        if (validateExit(data)) return;
                        try {
                            var obj = eval("(" + data + ")");
                            EasyMongo.update("executor",{name:seriesName,col:col},obj,function(err,count){
                                if(err) {
                                    console.log("Wrong input.Please retry.");
                                    updatedValue();
                                } else {
                                    if(count != 0) {
                                        console.log("R-E-P-L : success update executor config of " + seriesName);
                                    } else {
                                        console.log("R-E-P-L : updated 0 items.check your condition");
                                    }
                                }
                            });
                        } catch(e){
                            if(e) console.log("Wrong input.Please retry.");
                            updatedValue();
                        }
                    });
                })();
            });
        }
    },
    listExecutor : function(seriesName){
        if (!seriesName) {
            repl.question("Please input chain name:\n", function (data) {
                if(!data){
                    list();
                    return;
                }
                var seriesName = data;
                list(seriesName);
            });
        } else {
            list(seriesName);
        }
        function list(seriesName){
            EasyMongo.find("executor",{name:seriesName},function(err,docs){
                if(!!docs && docs.length != 0) {
                    console.log("R-E-P-L :  List Result...");
                    docs.forEach(function(obj){
                        console.log(obj);
                    });
                    console.log("R-E-P-L :  List Result Completed...");
                } else {
                    console.log("R-E-P-L : find 0 items.check your condition");
                }
            });
        }
    },
    deleteExecutor: function(seriesName){
        if (!seriesName) {
            repl.question("Please input executor name:\n", function (data) {
                if (validateExit(data)) return;
                var seriesName = data;
                deleteReq(seriesName);
            });
        } else {
            deleteReq(seriesName);
        }
        function deleteReq(seriesName) {
            function deleteAll(){
                EasyMongo.remove('executor',{name:seriesName},function(err,count){
                    if(err || count == 0) {
                        console.log("R-E-P-L : Deleted 0 items.check your condition");
                    } else {
                        console.log("R-E-P-L : Deleted "+count+" items.");
                    }
                });
            }
            repl.question("Input delete condition :\n", function (data) {
                if(!data) {
                    deleteAll();
                    return;
                }
                if (validateExit(data)) return;
                try {
                    var obj = eval("(" + data + ")");
                    if(obj.sequence) {
                        obj.sequence = parseInt(obj.sequence);
                    }
                    obj.series = seriesName;
                    EasyMongo.remove("name",obj,function(err,count){
                        if(err) {
                            console.log("DB ERROR..");
                        } else {
                            if(count != 0) {
                                console.log("R-E-P-L : success update chain config of " + seriesName);
                            } else {
                                console.log("R-E-P-L : updated 0 items.check your condition");
                            }
                        }
                    });
                } catch(e){
                    if(e) console.log("Wrong input.Please retry.");
                }
            });
        }
    }
};
/**
 *  command configuration
 * */
repl.command({
    request: [
        {
            '-a --add -s --series': function (data) {
                request.addRequest(data);
            }
        },
        {
            '-u --update' : function(data) {
                request.updateRequest(data);
            }
        },
        {
            '-l --list' : function(data){
                request.listRequest(data);
            }
        },
        {
            '-d --delete' : function(data){
                request.deleteRequest(data);
            }
        },
        {
            'none': function requestNone() {
                repl.question("Please input your operation.\n" +
                "(1.Add a request chain,2.update,3.list requests,4.delete):\n", function (data) {
                    validateExit(data);
                    switch (data) {
                        case "1":
                            request.addRequest();
                            break;
                        case "2":
                            request.updateRequest();
                            break;
                        case "3":
                            request.listRequest();
                            break;
                        case "4":
                            request.deleteRequest();
                            break;
                        default: console.log("Wrong input.Please choose between [1,2,3,4]");requestNone();break;
                    }
                });
            }
        }
    ],
    executor: [
        {
            '-a --add': function (data) {
                executor.addExecutor(data);
            }
        },
        {
            '-u --update' : function(data) {
                executor.updateExecutor(data);
            }
        },
        {
            '-l --list' : function(data){
                executor.listExecutor(data);
            }
        },
        {
            '-d --delete' : function(data){
                executor.deleteExecutor(data);
            }
        },
        {
            'none': function executorNone() {
                repl.question("Please input your operation.\n" +
                "(1.Add a executor chain,2.update,3.list executors,4.delete):\n", function (data) {
                    validateExit(data);
                    switch (data) {
                        case "1":
                            executor.addExecutor();
                            break;
                        case "2":
                            executor.updateExecutor();
                            break;
                        case "3":
                            executor.listExecutor();
                            break;
                        case "4":
                            executor.deleteExecutor();
                            break;
                        default: console.log("Wrong input.Please choose between [1,2,3,4]");executorNone();break;
                    }
                });
            }
        }
    ],
   /* crawler: [
        {
            '-a --add': function (data) {
                crawler.addCrawler(data);
            }
        },
        {
            '-u --update' : function(data) {
                crawler.updateCrawler(data);
            }
        },
        {
            '-l --list' : function(data){
                crawler.listCrawler(data);
            }
        },
        {
            '-d --delete' : function(data){
                crawler.deleteCrawler(data);
            }
        },
        {
            'none': function crawlerNone() {
                repl.question("Please input your operation.\n" +
                "(1.Add a crawler,2.update,3.list crawler,4.delete):\n", function (data) {
                    validateExit(data);
                    switch (data) {
                        case "1":
                            request.addCrawler();
                            break;
                        case "2":
                            request.updateCrawler();
                            break;
                        case "3":
                            request.listCrawler();
                            break;
                        case "4":
                            request.deleteCrawler();
                            break;
                        default: console.log("Wrong input.Please choose between [1,2,3,4]");crawlerNone();break;
                    }
                });
            }
        }
    ],
    analyzer: [
        {
            '-a --add': function (data) {
                analyzer.addRequest(data);
            }
        },
        {
            '-u --update' : function(data) {
                analyzer.updateRequest(data);
            }
        },
        {
            '-l --list' : function(data){
                analyzer.listRequest(data);
            }
        },
        {
            '-d --delete' : function(data){
                analyzer.deleteRequest(data);
            }
        },
        {
            'none': function analyzerNone() {
                repl.question("Please input your operation.\n" +
                "(1.Add a analyzer,2.update,3.list anlyzers,4.delete):\n", function (data) {
                    validateExit(data);
                    switch (data) {
                        case "1":
                            analyzer.addAnalyzer();
                            break;
                        case "2":
                            analyzer.updateAnalyzer();
                            break;
                        case "3":
                            analyzer.listAnalyzer();
                            break;
                        case "4":
                            analyzer.deleteAnalyzer();
                            break;
                        default: console.log("Wrong input.Please choose between [1,2,3,4]");analyzerNone();break;
                    }
                });
            }
        }
    ],
    meta: [
        {
            '-a --add': function (data) {
                meta.addeMeta(data);
            }
        },
        {
            '-u --update' : function(data) {
                meta.updateeMeta(data);
            }
        },
        {
            '-l --list' : function(data){
                meta.listeMeta(data);
            }
        },
        {
            '-d --delete' : function(data){
                meta.deleteMeta(data);
            }
        },
        {
            'none': function metaNone() {
                repl.question("Please input your operation.\n" +
                "(1.Add a meta data,2.update,3.list meta data,4.delete):\n", function (data) {
                    validateExit(data);
                    switch (data) {
                        case "1":
                            meta.addeMeta();
                            break;
                        case "2":
                            meta.updateeMeta();
                            break;
                        case "3":
                            meta.listeMeta();
                            break;
                        case "4":
                            meta.deleteeMeta();
                            break;
                        default: console.log("Wrong input.Please choose between [1,2,3,4]");metaNone();break;
                    }
                });
            }
        }
    ],*/
    'turtle':[
        {
            '-s --startup --setup': function setUpTurtle(){
                var crawler = "";
                repl.question("Input Crawler Name :\n",function(data){
                    validateExit(data);
                    crawler = data;
                }).question("Input Analyzer Name :\n",function(data){
                    validateExit(data);
                    EasyMongo.find('crawler',{name:crawler},function(err, docs){
                       if(err || docs.length == 0) {
                           console.log("Wrong Crawler Input.Please check your input.");
                           setUpTurtle();
                       } else {
                           EasyMongo.find('analyzer',{name:data},function(err,docs){
                               if(err || docs.length == 0) {
                                   console.log("Wrong Crawler Input.Please check your input.");
                                   setUpTurtle();
                               } else {
                                   console.log('setup turtle');
                                   //todo
                               }
                           });
                       }
                    });
                    if(crawler.length == 0) {
                        console.log("Wrong Input.Please check your input.");
                        setUpTurtle();
                    }
                });
            },
            '-d --destroy' : function(){
                //todo
                cl.manualStop();
            },
            'none' : function(){
                console.log("Usage : turtle [param].Please choose a param between [-s --startup --setup -d --destroy]");
            }
        }
    ],
    'help': [
        {
            '-c --command': function (data) {
                if (validateExit(data, true)) {
                    console.log('Please input what command you want to know.\ncommands include [request, executor, crawler, analyzer, meta,turtle]');
                } else {
                    switch (data) {
                        case "executor":
                        case "analyzer" :
                        case "crawler" :
                        case "meta" :
                        case "request":
                            console.log(data + " is a config command.Params include [-a -u -d -l].For request, -s = -a");
                            console.log("[config command] [-a --add] 'chain name' means add a new config.\n" +
                            "[config command] [-u --update] 'chain name' means update config.\n" +
                            "[config command] [-d --delete] 'chain name' [-seq --sequence] means delete config.\n" +
                            "[config command] [-l --list] ['chain name'] means list all or certain config.");
                            break;
                        case "turtle" :
                            console.log("turtle is a tool to start A Turtle or manage turtles. Params include [-s -d]");
                            console.log("turtle [-s --startup --setup] means set up a crawler-analyzer system\n" +
                            "turtle [-d --destroy] means stop current crawler system manually");
                            break;
                    }
                }
            },
            'none': function(){
                console.log("Usage : help [-c --command] 'command' commands include [request, executor, crawler, analyzer, meta,turtle]");
            }
        }
    ],
    'exit': [
        {
            'none': function () {
                console.log('Exit All SIGNAL emitted.Bye~..');
                process.exit(0);
            }
        }
    ]
});

function validateExit(data, mode) {
    if (!data || data == 'exit' || data == 'finish' || data.trim().length == 0) {
        if (!mode)
            console.log('Exit SIGNAL emitted.Please input your command...');
        return true;
    }
    return false;
}